package com.yet.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import com.yet.annotation.RpcAutowrie;
import com.yet.container.registry.RegistryMeta.ServiceMeta;
import com.yet.container.remote.ResponseFuture;
import com.yet.container.remote.netty.client.Client;
import com.yet.dto.Request;

/**
 * 代理主要实现
 */
public class ClientInvocationHandler implements InvocationHandler {

	public static final int DEFAULT_TIMEOUT = 2000;

	private final RpcAutowrie autowrie;

	private final Client client;

	private int timeout = DEFAULT_TIMEOUT;

	public ClientInvocationHandler(RpcAutowrie autowrie, Client client) {
		super();
		this.autowrie = autowrie;
		this.client = client;
	}

	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Request request = new Request();
		request.setId(UUID.randomUUID().toString());
		request.setMethodName(method.getName());
		request.setParameterTypes(method.getParameterTypes());
		request.setClassName(method.getDeclaringClass());
		request.setParameters(args);
		request.setServiceMeta(new ServiceMeta(autowrie));
		ResponseFuture future = client.send(request);
		if (Void.class.isAssignableFrom(method.getReturnType())) {
			return null;
		}
		if (Future.class.isAssignableFrom(method.getReturnType())) {
			return future;
		}
		return future.get(timeout > 0 ? timeout : DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
	}

}
